<template>
  <div class="game-container">
    <h1>坦克大战</h1>
    <div class="game-stats">
      <p>得分: {{ score }}</p>
      <p>生命值: {{ playerHealth }}</p>
    </div>
    <canvas ref="gameCanvas" width="800" height="600"></canvas>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';

// 游戏状态
const score = ref(0);
const playerHealth = ref(100);
const gameCanvas = ref<HTMLCanvasElement | null>(null);
let gameLoop: number;
let ctx: CanvasRenderingContext2D;

// 玩家坦克
const player = {
  x: 400,
  y: 500,
  width: 40,
  height: 40,
  speed: 5,
  direction: 0, // 角度，0表示向上
  bullets: [] as Bullet[],
};

// 敌人坦克
interface Enemy {
  x: number;
  y: number;
  width: number;
  height: number;
  speed: number;
  direction: number;
  bullets: Bullet[];
}

const enemies = ref<Enemy[]>([]);

// 子弹
interface Bullet {
  x: number;
  y: number;
  speed: number;
  direction: number;
}

// 按键状态
const keys = {
  ArrowUp: false,
  ArrowDown: false,
  ArrowLeft: false,
  ArrowRight: false,
  Space: false,
};

// 初始化游戏
const initGame = () => {
  if (!gameCanvas.value) return;
  ctx = gameCanvas.value.getContext('2d')!;
  
  // 生成初始敌人
  spawnEnemies();
  
  // 开始游戏循环
  gameLoop = requestAnimationFrame(update);
};

// 生成敌人
const spawnEnemies = () => {
  for (let i = 0; i < 3; i++) {
    enemies.value.push({
      x: Math.random() * 700 + 50,
      y: Math.random() * 200 + 50,
      width: 40,
      height: 40,
      speed: 2,
      direction: Math.PI,
      bullets: [],
    });
  }
};

// 更新游戏状态
const update = () => {
  // 清空画布
  ctx.clearRect(0, 0, 800, 600);
  
  // 更新玩家位置
  updatePlayer();
  
  // 更新敌人
  updateEnemies();
  
  // 更新子弹
  updateBullets();
  
  // 检测碰撞
  checkCollisions();
  
  // 绘制游戏画面
  draw();
  
  // 继续游戏循环
  gameLoop = requestAnimationFrame(update);
};

// 更新玩家状态
const updatePlayer = () => {
  // 移动
  if (keys.ArrowUp) player.y -= player.speed;
  if (keys.ArrowDown) player.y += player.speed;
  if (keys.ArrowLeft) {
    player.x -= player.speed;
    player.direction = -Math.PI / 2;
  }
  if (keys.ArrowRight) {
    player.x += player.speed;
    player.direction = Math.PI / 2;
  }
  
  // 边界检查
  player.x = Math.max(0, Math.min(760, player.x));
  player.y = Math.max(0, Math.min(560, player.y));
  
  // 发射子弹
  if (keys.Space) {
    fireBullet(player);
    keys.Space = false; // 防止连续发射
  }
};

// 更新敌人状态
const updateEnemies = () => {
  enemies.value.forEach(enemy => {
    // 简单的AI：朝向玩家移动
    const dx = player.x - enemy.x;
    const dy = player.y - enemy.y;
    enemy.direction = Math.atan2(dy, dx);
    
    enemy.x += Math.cos(enemy.direction) * enemy.speed;
    enemy.y += Math.sin(enemy.direction) * enemy.speed;
    
    // 随机发射子弹
    if (Math.random() < 0.02) {
      fireBullet(enemy);
    }
  });
};

// 发射子弹
const fireBullet = (tank: Enemy | typeof player) => {
  tank.bullets.push({
    x: tank.x + tank.width / 2,
    y: tank.y + tank.height / 2,
    speed: 8,
    direction: tank.direction,
  });
};

// 更新子弹位置
const updateBullets = () => {
  // 更新玩家子弹
  player.bullets = player.bullets.filter(bullet => {
    bullet.x += Math.cos(bullet.direction) * bullet.speed;
    bullet.y += Math.sin(bullet.direction) * bullet.speed;
    return bullet.x >= 0 && bullet.x <= 800 && bullet.y >= 0 && bullet.y <= 600;
  });
  
  // 更新敌人子弹
  enemies.value.forEach(enemy => {
    enemy.bullets = enemy.bullets.filter(bullet => {
      bullet.x += Math.cos(bullet.direction) * bullet.speed;
      bullet.y += Math.sin(bullet.direction) * bullet.speed;
      return bullet.x >= 0 && bullet.x <= 800 && bullet.y >= 0 && bullet.y <= 600;
    });
  });
};

// 检测碰撞
const checkCollisions = () => {
  // 检查玩家子弹是否击中敌人
  player.bullets.forEach((bullet, bulletIndex) => {
    enemies.value.forEach((enemy, enemyIndex) => {
      if (checkBulletCollision(bullet, enemy)) {
        player.bullets.splice(bulletIndex, 1);
        enemies.value.splice(enemyIndex, 1);
        score.value += 100;
        
        // 生成新敌人
        if (enemies.value.length < 3) {
          spawnEnemies();
        }
      }
    });
  });
  
  // 检查敌人子弹是否击中玩家
  enemies.value.forEach(enemy => {
    enemy.bullets.forEach((bullet, bulletIndex) => {
      if (checkBulletCollision(bullet, player)) {
        enemy.bullets.splice(bulletIndex, 1);
        playerHealth.value -= 10;
        
        if (playerHealth.value <= 0) {
          // 游戏结束
          cancelAnimationFrame(gameLoop);
        }
      }
    });
  });
};

// 检查子弹碰撞
const checkBulletCollision = (bullet: Bullet, target: Enemy | typeof player) => {
  return (
    bullet.x >= target.x &&
    bullet.x <= target.x + target.width &&
    bullet.y >= target.y &&
    bullet.y <= target.y + target.height
  );
};

// 绘制游戏画面
const draw = () => {
  // 绘制玩家坦克
  drawTank(player, '#00ff00');
  
  // 绘制敌人坦克
  enemies.value.forEach(enemy => {
    drawTank(enemy, '#ff0000');
  });
  
  // 绘制子弹
  ctx.fillStyle = '#ffff00';
  player.bullets.forEach(bullet => {
    ctx.beginPath();
    ctx.arc(bullet.x, bullet.y, 3, 0, Math.PI * 2);
    ctx.fill();
  });
  
  enemies.value.forEach(enemy => {
    enemy.bullets.forEach(bullet => {
      ctx.beginPath();
      ctx.arc(bullet.x, bullet.y, 3, 0, Math.PI * 2);
      ctx.fill();
    });
  });
};

// 绘制坦克
const drawTank = (tank: Enemy | typeof player, color: string) => {
  ctx.save();
  ctx.translate(tank.x + tank.width / 2, tank.y + tank.height / 2);
  ctx.rotate(tank.direction);
  
  // 坦克主体
  ctx.fillStyle = color;
  ctx.fillRect(-tank.width / 2, -tank.height / 2, tank.width, tank.height);
  
  // 炮管
  ctx.fillStyle = '#000';
  ctx.fillRect(0, -2, tank.width / 2, 4);
  
  ctx.restore();
};

// 键盘事件处理
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.code in keys) {
    keys[e.code as keyof typeof keys] = true;
  }
};

const handleKeyUp = (e: KeyboardEvent) => {
  if (e.code in keys) {
    keys[e.code as keyof typeof keys] = false;
  }
};

// 生命周期钩子
onMounted(() => {
  window.addEventListener('keydown', handleKeyDown);
  window.addEventListener('keyup', handleKeyUp);
  initGame();
});

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
  window.removeEventListener('keyup', handleKeyUp);
  cancelAnimationFrame(gameLoop);
});
</script>

<style scoped>
.game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

.game-stats {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
  font-size: 1.2em;
  font-weight: bold;
}

canvas {
  border: 2px solid #333;
  background: #000;
}
</style> 